package beauty.other;

import org.apache.commons.lang3.math.Fraction;
import org.apache.commons.lang3.tuple.Pair;

/**
 * 趣味题
 * Created by Robo on 2018/1/25.
 */
public class InterestSubject {
    public static void main(String[] args) {
//        System.out.println("兔子n个月后个数"+calcMonthRabbitNumber(6, 2));

//        for (int i = 100; i < 1000; i++) {
//            if (isNarcissus(i)) {
//                System.out.println(i + "是水仙花");
//            }
//        }

//        System.out.println("一球从100米高度自由落下，求它在 第10次落地时，共经过多少米？第10次反弹多高");
//        System.out.println(freeFallDown(100,10,0));

//        System.out.println(monkeyEatPeach());

//        System.out.println(calcPai(1000000));

        System.out.println(calcFraction(20));
    }

    /**
     * 题目：古典问题：有一对兔子，从出生后第3个月起每个月都生一对兔子，小兔子长到第三个月后每个月又生一对兔子，假如兔子都不死，问每个月的兔子总数为多少？
     */
    private static Integer calcMonthRabbitNumber(int monthes, int initNum) {
        Integer result;
        if (initNum < 2) {
            return 0;
        }
        if (monthes < 3) {
            return initNum;
        }
        int birthTimes = monthes - 2;
        if (birthTimes == 1) {
            result = initNum * 2;
        } else {
            result = initNum + calcMonthRabbitNumber(monthes - 3, initNum * 2);
        }
        return result;
    }

    /**
     * 打印出所有的 "水仙花数 "，所谓 "水仙花数 "是指一个三位数，其各位数字立方和等于该数本身。例如：153是一个 "水仙花数 "，因为153=1的三次方＋5的三次方＋3的三次方。
     */
    private static Boolean isNarcissus(int number) {
        if (number < 100 || number > 999) {
            return false;
        } else {
            int hundred = number / 100;
            int ten = (number - hundred * 100) / 10;
            int single = number % 10;
            return number == Math.pow(hundred, 3) + Math.pow(ten, 3) + Math.pow(single, 3);
        }
    }

    /**
     * 题目：一球从100米高度自由落下，每次落地后反跳回原高度的一半；再落下，求它在 第10次落地时，共经过多少米？第10次反弹多高？
     */
    private static Pair<Integer, Integer> freeFallDown(int height, int onGroundTimes,int distance) {
        int rebound ;
        if (onGroundTimes == 1) {
            rebound = height / 2;
            distance = distance + height;
        }else{
            return freeFallDown(height / 2, onGroundTimes - 1, (int) (distance+1.5*height));
        }
        return Pair.of(rebound, distance);
    }

    /**
     * 题目：猴子吃桃问题：猴子第一天摘下若干个桃子，当即吃了一半，还不瘾，又多吃了一个
     * 第二天早上又将剩下的桃子吃掉一半，又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。
     * 到第10天早上想再吃时，见只剩下一个桃子了。求第一天共摘了多少。
     */
    private static int monkeyEatPeach() {
        int peach = 1;
        for (int passedDay = 10; passedDay > 1; passedDay--) {
            peach = 2 * (peach + 1);
        }
        return peach;
    }

    /**
     * 大概就是以正方形的变长为1，圆形的半径为1，那么我知道知道第一象限圆的面积为π/4，然后正方形的面积为1，
     * 那么我们可以通过落入圆形中的点数占的比例来估计π的值
     */
    private static Double calcPai(int sample) {
        double pai = 0.0;
        double x, y;
        int res = 0;//在圆范围的点个数
        for (int i = 0; i < sample; i++) {
            x = Math.random();
            y = Math.random();
            if (x * x + y * y < 1) {
                res++;
            }
        }
        return 4.0 * res / sample;
    }

    /**
     * 2/1，3/2，5/3，8/5，13/8，21/13...前20项之和。
     */

    private static Double calcFraction(int count) {
        int numerator , denominator;
        numerator = getFibonacci(count+1);
        denominator = getFibonacci(count);
        if (count == 1) {
            return Fraction.getFraction(numerator, denominator).doubleValue();
        }else{
            return Fraction.getFraction(numerator, denominator).doubleValue() + calcFraction(count - 1);
        }
    }

    private static int getFibonacci(int index) {
        if(index<1) return 0;
        else if(index==1) return 1;
        else if(index==2) return 2;
        else{
            return getFibonacci(index - 2) + getFibonacci(index - 1);
        }
    }




}

